﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic.Statistics;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Commons.ViewModels.Chart;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities.Models;
using NLog;

namespace Atmk.WaterMeter.MIS.Logic.Mock
{
    public class ChartLogicMock : IChartLogic
    {
        protected Logger _logger = LogManager.GetCurrentClassLogger();
        private Dictionary<string, int> _MonthCount = new Dictionary<string, int>();
        /// <summary>
        /// 同步获取
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public async Task<ChartDatas> GetChart(string projectId)
        {
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var chatResult = new ChartDatas();
                    //费用提醒
                    chatResult.costReminderData = await GetCostReminderData();
                    //关阀提醒
                    chatResult.closingvalveData = await GetClosingvalveData();
                    //首页小模块（统计信息）
                    chatResult.statisticsInfoData = new StatisticsInfoData
                    {
                        districtCount = _context.District.Count(m => m.ProjectId == projectId),
                        meterCount = _context.Meter.Count(m => m.ProjectId == projectId),
                        ownerCount = _context.Meter.Count(m => m.ProjectId == projectId),
                        //真实的在线率
                        //onlineRatio = Convert.ToDouble((_context.MeterReadingRecord.Where(m => Convert.ToDateTime(m.ReadTime).Month == DateTime.Now.Month).GroupBy(m => m.CtdeviceId).Count() / Convert.ToDouble(_context.Meter.Count(m => m.ProjectId == projectId)) * 100).ToString("f2"))
                        onlineRatio = 99.2
                    };

                    //首页小模块（用水情况(年 and 月)）
                    chatResult.waterConsumptionInfoData = new WaterConsumptionInfoData
                    {
                        yesterday = (int)_context.SettlementDay.Where(m => m.ReadTime == DateTime.Now.AddDays(-1).Date&&m.Dosage>0).Sum(m => m.Dosage),
                        lastMonth = (int)_context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.AddMonths(-1).Year && m.ReadTime.Month == DateTime.Now.AddMonths(-1).Month).Sum(m => m.Dosage),
                        nowMonth = (int)_context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.Year && m.ReadTime.Month == DateTime.Now.Month).Sum(m => m.Dosage),
                        sameMonth = (int)_context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.AddYears(-1).Year && m.ReadTime.Month == DateTime.Now.Month).Sum(m => m.Dosage),
                        yearDosage = (int)_context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.Year).Sum(m => m.Dosage),
                        lastYearDosage = (int)_context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.AddYears(-1).Year).Sum(m => m.Dosage),
                        sameYear = (int)_context.SettlementDay.Where(m => m.ReadTime > Convert.ToDateTime(DateTime.Now.AddYears(-1).Year+"-01-01") && m.ReadTime <= DateTime.Now.AddYears(-1).Date).Sum(m => m.Dosage)
                    };

                    //chatResult.districtReadRatioData = GetDistrictReadRatioData();

                    //chatResult.yesterdayConsumptionData = GetYesterdayConsumptionData();
                    //chatResult.lastMonthDistrictConsumptionsCountData = await GetLastMonthWaterConsumptionsCountData(projectId);
                    //chatResult.lastSeasonWaterConsumptionsCountData = GetLastSeasonWaterConsumptionsCountData(projectId);
                    //chatResult.lastYearWaterConsumptionsCountData = await GetLastYearWaterConsumptionsCountData(projectId);

                    return chatResult;
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public async Task<ChartDatas> GetChart2(string projectId)
        {
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var chatResult = new ChartDatas();
                    //各片区抄表情况
                    chatResult.districtReadRatioData = GetDistrictReadRatioData();
                    var test = GetLastMonthWaterConsumptionsCountData(projectId);
                    //备份 门牌号 用量排行
                    //chatResult.yesterdayConsumptionData = GetYesterdayConsumptionData();
                    //上季度片区用水情况
                    chatResult.lastSeasonWaterConsumptionsCountData = GetLastSeasonWaterConsumptionsCountData(projectId);
                    return chatResult;
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public async Task<ChartDatas> GetChart2_1(string projectId)
        {
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var chatResult = new ChartDatas();
                    //上月用水情况
                    chatResult.lastMonthDistrictConsumptionsCountData = await GetLastMonthWaterConsumptionsCountData(projectId);
                    return chatResult;
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public async Task<ChartDatas> GetChart3(string projectId)
        {
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var chatResult = new ChartDatas();
                    //上年片区用水情况
                    chatResult.lastYearWaterConsumptionsCountData = await GetLastYearWaterConsumptionsCountData(projectId);
                    return chatResult;
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public ChartDatas GetChart4(string projectId)
        {
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var chatResult = new ChartDatas();
                    chatResult.firstThreeDays = GetFirstThreeDays(projectId);
                    return chatResult;
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #region private

        private Task<YearWaterConsumptionsCountData> GetLastYearWaterConsumptionsCountData(string projectId)
        {
            try
            {
                return Task.Run(() =>
                {
                    using (var _context = ContextBuilder.Build())
                    {
                        var districts = _context.District.Where(m => m.ProjectId == projectId);
                        var meter_group = _context.Meter.GroupBy(m => m.DistrictId);
                        //取日结算表上个月的数据
                        var settlementDays = _context.SettlementDay.Where(m => m.ReadTime.Year == DateTime.Now.AddYears(-1).Year).GroupBy(m => m.ReadTime.Month);
                        var r = new YearWaterConsumptionsCountData
                        {
                            total = "0",
                            list = new List<WaterConsumptionsCountListItem>(),
                            year = DateTime.Now.Year
                        };
                        foreach (var item in meter_group)
                        {
                            var tempp = new WaterConsumptionsCountListItem
                            {
                                districtId = item.Key,
                                districtName = districts.FirstOrDefault(m => m.Id == item.Key)?.Name,
                                waterConsumptions = new List<double>()
                            };
                            int tempkey = settlementDays.Select(m => m.Key).OrderBy(m => m).FirstOrDefault();
                            for (int i = 1; i < tempkey; i++)
                            {
                                tempp.waterConsumptions.Add(0);
                            }
                            foreach (var item1 in settlementDays)
                            {
                                var ttt = item1.Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage);
                                tempp.waterConsumptions.Add(ttt);
                            }

                            //for (int i = 1; i <= 12; i++)
                            //{
                            //    settlementDays.
                            //    if (settlementDays)
                            //    {

                            //    }
                            //    settlementDays.Where(m => m.Key == i).
                            //    tempp.waterConsumptions.Add(settlementDays.Where(m => Convert.ToDateTime(m.ReadTime).Month == i).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));
                            //}
                            r.list.Add(tempp);
                        }
                        return r;
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.Error("首页小模块取数错误（月用水量）：" + ex.Message);
                return Task.Run(() => new YearWaterConsumptionsCountData() { total = "0", list = null, year = 1999 });
            }
        }

        //上季度用量
        private WaterConsumptionsCountData GetLastSeasonWaterConsumptionsCountData(string projectId)
        {
            using (var _context = ContextBuilder.Build())
            {
                var districts = _context.District.Where(m => m.ProjectId == projectId);
                var meter_group = _context.Meter.GroupBy(m => m.DistrictId);
                var jd = GetJiDu();
                var settlementDays = _context.SettlementDay.Where(m => m.ReadTime > DateTime.Now.AddMonths(-7)).ToList();
                var r = new WaterConsumptionsCountData
                {
                    total = "0",
                    list = new List<WaterConsumptionsCountListItem>()
                };
                foreach (var item in meter_group)
                {
                    List<double> temp = new List<double>();
                    foreach (var item1 in jd)
                    {
                        if (new int[] { 10, 11, 12 }.Contains(item1))
                        {
                            temp.Add(settlementDays.Where(m => m.ReadTime.Year == DateTime.Now.AddYears(-1).Year && m.ReadTime.Month == item1).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));
                        }
                        else
                        {
                            temp.Add(settlementDays.Where(m => m.ReadTime.Year == DateTime.Now.Year && m.ReadTime.Month == item1).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));
                        }
                    }

                    r.list.Add(new WaterConsumptionsCountListItem
                    {
                        districtId = item.Key,
                        districtName = districts.FirstOrDefault(m => m.Id == item.Key)?.Name,
                        waterConsumptions = temp
                    });
                }
                return r;
            }
        }
        //上月用水量
        private Task<WaterConsumptionsCountData> GetLastMonthWaterConsumptionsCountData(string projectId)
        {
            return Task.Run(() =>
            {
                using (var _context = ContextBuilder.Build())
                {
                    var districts = _context.District.Where(m => m.ProjectId == projectId);
                    var meter_group = _context.Meter.GroupBy(m => m.DistrictId);
                    //取日结算表上个月的数据
                    var settlementDays = _context.SettlementDay.Where(m => m.ReadTime.Month == DateTime.Now.AddMonths(-1).Month);
                    var r = new WaterConsumptionsCountData
                    {
                        total = districts.Count().ToString(),
                        list = new List<WaterConsumptionsCountListItem>()
                    };
                    foreach (var item in meter_group)
                    {
                        r.list.Add(new WaterConsumptionsCountListItem
                        {
                            districtId = item.Key,
                            districtName = districts.FirstOrDefault(m => m.Id == item.Key)?.Name,
                            waterConsumptions = new List<double>() { settlementDays.Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage) }
                        });
                    }
                    return r;
                }
            });
        }


        private YesterdayConsumptionData GetYesterdayConsumptionData()
        {
            var r = new YesterdayConsumptionData
            {
                total = 3.ToString(),
                list = new List<YesterdayConsumptionListItem>()
            };
            for (var i = 0; i < 3; i++)
            {
                var item = new YesterdayConsumptionListItem
                {
                    ownerId = Guid.NewGuid().ToString(),
                    houseNumber = $"门牌号{i + 1}",
                    waterConsumption = new Random(Simple.GetRandomSeed()).Next(1500, 3680)
                };
                r.list.Add(item);
            }
            return r;
        }

        private DistrictReadRatioData GetDistrictReadRatioData()
        {
            var len = ChartDateCatchMock.DistrictList.Length;
            var r = new DistrictReadRatioData
            {
                total = len.ToString(),
                list = new List<DistrictReadRatioItem>()
            };
            for (var i = 0; i < len; i++)
            {
                var dicName = ChartDateCatchMock.DistrictList[i];
                var item = new DistrictReadRatioItem
                {
                    districtId = Guid.NewGuid().ToString(),
                    districtName = $"{dicName}",
                    readRatio = (new Random(Simple.GetRandomSeed()).Next(9000,
                                    10000)) / 100.00
                };
                r.list.Add(item);
            }
            return r;
        }
        //关门阀 的业主
        private Task<ClosingvalveData> GetClosingvalveData()
        {
            return Task.Run(() =>
            {
                using (var _context = ContextBuilder.Build())
                {
                    var temp = new List<MeterReadingRecord>();
                    var mrr_group = _context.MeterReadingRecord.GroupBy(m => m.CtdeviceId).Select(m => m.OrderByDescending(m1 => m1.ReadTime));
                    foreach (var item in mrr_group)
                    {
                        if (item.First().ValveState == 0)
                        {
                            temp.Add(item.First());
                        }
                    }
                    string[] CtdeviceIds = temp.Select(m => m.CtdeviceId).ToArray();
                    var ownerids = _context.Meter.Where(m => CtdeviceIds.Contains(m.CtdeviceId)).Select(m => m.OwnerId).ToArray();
                    var owners = _context.Owner.Where(m => ownerids.Contains(m.Id)).ToList();
                    var r = new ClosingvalveData
                    {
                        total = mrr_group.Count().ToString(),
                        list = new List<ClosingValveOwnerItem>()
                    };
                    foreach (var item in owners)
                    {
                        r.list.Add(new ClosingValveOwnerItem()
                        {
                            ownerId = item.Id,
                            houseNumber = item.HouseNumber,
                            ownerName = item.Name
                        });
                    }
                    return r;
                }
            });
        }
        //费用提醒
        private Task<CostReminderData> GetCostReminderData()
        {
            return Task.Run(() =>
            {
                using (var _context = ContextBuilder.Build())
                {
                    var orders = _context.OrderDetail.Where(m => m.Money < -10).GroupBy(m => m.OwnerId);
                    string[] order_ownerids = orders.Select(m1 => m1.Key).ToArray();
                    var owners = _context.Owner.Where(m => order_ownerids.Contains(m.Id)).ToList();
                    var r = new CostReminderData
                    {
                        total = orders.Count().ToString(),
                        list = new List<CostReminderItem>()
                    };
                    foreach (var item in orders)
                    {
                        if (item.Sum(m1 => m1.Money) < 0)
                        {
                            r.list.Add(new CostReminderItem()
                            {
                                ownerId = item.Key,
                                ownerName = owners.First(m1 => m1.Id == item.Key).Name,
                                balance = item.Sum(m1 => m1.Money)
                            });
                        }
                    }
                    r.list = r.list.OrderBy(m => m.balance).Take(30).ToList();
                    return r;
                }
            });
        }

        //前三天用量
        private WaterConsumptionsCountData GetFirstThreeDays(string projectId)
        {
            using (var _context = ContextBuilder.Build())
            {
                var districts = _context.District.Where(m => m.ProjectId == projectId);
                var meter_group = _context.Meter.GroupBy(m => m.DistrictId);
                var settlementDays = _context.SettlementDay.Where(m => m.ReadTime >= DateTime.Now.AddDays(-4)).ToList();
                var r = new WaterConsumptionsCountData
                {
                    total = "0",
                    list = new List<WaterConsumptionsCountListItem>()
                };
                foreach (var item in meter_group)
                {
                    List<double> temp = new List<double>();
                    temp.Add(settlementDays.Where(m => m.ReadTime == DateTime.Now.AddDays(-1).Date).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));
                    temp.Add(settlementDays.Where(m => m.ReadTime == DateTime.Now.AddDays(-2).Date).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));
                    temp.Add(settlementDays.Where(m => m.ReadTime == DateTime.Now.AddDays(-3).Date).Where(m => item.Select(m1 => m1.CtdeviceId).Contains(m.CtdeviceId)).Sum(m => m.Dosage));

                    r.list.Add(new WaterConsumptionsCountListItem
                    {
                        districtId = item.Key,
                        districtName = districts.FirstOrDefault(m => m.Id == item.Key)?.Name,
                        waterConsumptions = temp
                    });
                }
                return r;
            }
        }
        #endregion

        public int[] GetJiDu()
        {
            if (DateTime.Now.Month >= 10)
            {
                return new int[] { 7, 8, 9 };
            }
            else if (DateTime.Now.Month >= 7)
            {
                return new int[] { 4, 5, 6 };
            }
            else if (DateTime.Now.Month >= 4)
            {
                return new int[] { 1, 2, 3 };
            }
            else if (DateTime.Now.Month >= 1)
            {
                return new int[] { 10, 11, 12 };
            }
            return null;
        }
    }
}